#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""University of New Hampshire data format

Copyright (c) 2014 Christian T. Steigies <steigies@physik.uni-kiel.de>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

This module offers functions to read NM data in ASCII from an FTP server
as used in New Hampshire and return data in the format as used by NMDB."""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

from datetime import datetime
import os
import urllib2

from nmdb.station.station_data import check_data, check_pressure
from nmdb.tools.configtool import parse_options

new_hampshire_station = ["clmx", "drhm", "hle1", "hlea", "huan", "ldvl", "mtws"]
new_hampshire_longnames = {"clmx": "Climax",           # 1951 -- 2006
                           "drhm": "Durham",
                           "hle1": "Haleakala",        # 1991 -- 2006
                           "hlea": "Haleakala",        # 1991 -- 2006
                           "huan": "Huancayo",         # 1953 -- 1992
                           "ldvl": "Leadville",
                           "mtws": "Mount Washington"
                           }

## --------------------------------------------------------------------------
def read_rt(options, station, data_type, year, month, day):
    """read realtime data

    options     verbose, dryrun, ...
    station     station short name, must be valid station
    data_type   "1m", "1h", "env", "meta"
    year        integer (1950-9999), may not be None
    month       integer (1-12), if None, read month 1-12
    day         integer (1-31), if None, read day 1-31
    
    return list of values in nmdb format
    """

    if station in new_hampshire_station:
        pass
    else:
        raise ValueError  # wrong station

    if data_type in ["1h"]:
        value = []
    elif data_type in ["1m"]:
        return None
    elif data_type in ["env", "meta"]:
        return None
    else:
        raise ValueError  # illegal data_type

    return value

## --------------------------------------------------------------------------
def read_rev(options, station, data_type, year, month, day):
    """read revised data

    options     verbose, dryrun, ...
    station     station short name, must be valid station
    data_type   "1m", "1h", "env", "meta"
    year        integer (1950-9999), may not be None
    month       integer (1-12), if None, read month 1-12
    day         integer (1-31), if None, read day 1-31

    return list of values in nmdb format
    """

    if station in new_hampshire_station:
        pass
    else:
        raise ValueError  # wrong station

    if data_type in ["1h"]:
        value = read_ftp_1h(options, station, data_type, year, month, day)
    elif data_type in ["1m"]:
        return None
    elif data_type in ["env", "meta"]:
        return None
    else:
        raise ValueError  # illegal data_type

    return value

## --------------------------------------------------------------------------
def read_ftp_1h(options, station, data_type, year, month, day=None):
    """read hourly data from UNH FTP
  The University of Chicago       Version 1.2   January 18, 1999
If you use these data in a publication, please acknowledge the
University of Chicago, "National Science Foundation Grant ATM-9613963".

Explanation of Data Formats:

 First Field: Day in format Month/DayOfMonth/Year
Second Field: HH at start of hour (i.e average covers period from
              HH:00:00 to HH+1:00:00)
 Third Field: Seconds since 00:00:00 on 1 January 1904 at start of hour
Fourth Field: Counts/Hour, prescaled by 100 (for Climax IGY Neutron Monitor)
              -1 indicates missing hour

01/01/1951 00 1483228800          -1
01/01/1951 01 1483232400        4328
01/01/1951 02 1483236000        4451
    """
        
    data = []
    interval = 3600
    sname = new_hampshire_longnames[station]
    
    #useftp = False
    useftp = True
    if useftp:  # read directly from FTP server
        ftpserver="ftp://ulysses.sr.unh.edu/NeutronMonitor/Hourly"
    else:  # read from local copy
        ftpserver = os.environ["HOME"]+"/data/UNH/Hourly"
    filename = "%s%s/%s%04i" % (ftpserver, sname, sname, year)
    print "reading", filename

    try:
        if useftp:
            myfile = urllib2.urlopen(filename)
        else:
            myfile = open(filename, "r")
        line = True
        while line:
            line = myfile.readline()
            if line[0:6] == "01/01/":
                # found beginning of data
                break

        while line:
            # Haleakala has two monitors
            # Huancayo has also cutoff drift corrected data
            if station in ["clmx"]:
                (mydate, myhour, igortime, corr) = line.split()
                ceff = corr
            elif station in ["huan"]:  # use second column as ceff
                (mydate, myhour, igortime, corr, ceff) = line.split()
            elif station in ["hle1"]:  # IGY?
                (mydate, myhour, igortime, corr, corr2) = line.split()
                ceff = corr
            elif station in ["hlea"]:  # NM64?
                (mydate, myhour, igortime, corr2, corr) = line.split()
                ceff = corr
            else:
                raise ValueError  # undefined station

            (mymonth, myday, myyear) = mydate.split("/")
            myyear = int(myyear)
            mymonth = int(mymonth)
            myday = int(myday)
            myhour = int(myhour)
            timestamp = datetime(myyear, mymonth, myday, myhour, 0, 0)

            # round to three digits
            if float(corr) < 0.:
                corr = None
            else:
                corr = round(100.*float(corr)/interval, 3)

            if float(ceff) < 0.:
                ceff = None
            else:
                ceff = round(100.*float(ceff)/interval, 3)

            press = None
            uncorr = None
            #press = round(float(press), 2)
            #uncorr = round(float(uncorr)/interval, 3)
            
            # basic data quality checks
            #uncorr = check_data(uncorr, cr_min=10., cr_max=10000.)
            #press = check_pressure(press, p_min=900., p_max=1070.)
            corr = check_data(corr, cr_min=10., cr_max=10000.)
            ceff = check_data(ceff, cr_min=10., cr_max=10000.)

            # return only requested data
            if (day and day != myday) or (month and month != mymonth) or (year and year != myyear):
                pass
            else:
                # order as in NMDB
                data.append([timestamp, interval, uncorr, ceff, corr, press])

            line = myfile.readline()

        return data

    except IOError:
        print "file %s not found" % (filename)
    except urllib2.URLError:
        print "file %s not found", filename

## --------------------------------------------------------------------------
def main():
    print "This is the new_hampshire module."

    (options, args) = parse_options("upload")
    if options.verbose > 1:
        print "options:", options
        print "args:", args
    if options.dryrun:
        print "dryrun: not sending any data to NMDB"

    station = "hle1"
    data_type="1h"
    #data_type="1m"
    year = 1992
    month = 2
    day = 21

    data = read_rev(options, station, data_type, year, month, day)
    #data = read_rt(options, station, data_type, year, month, day)
    for line in data:
        print line


## --------------------------------------------------------------------------
if __name__ == '__main__':
    main()
